package cn.melonlib.nars.names.comp.service;

import cn.hutool.core.util.IdUtil;
import cn.melonlib.cores.commons.comp.service.impl.WorkerBasicService;
import cn.melonlib.cores.commons.exceptions.WorkerServiceException;
import cn.melonlib.cores.identification.comp.messenger.MessengerUtils;
import cn.melonlib.cores.jpa.model.bean.collections.JsonMap;
import cn.melonlib.cores.jpa.model.bean.impl.DefaultQuery;
import cn.melonlib.cores.model.anno.*;
import cn.melonlib.nars.names.model.enmus.FileType;
import cn.melonlib.nars.names.model.entity.MelonDirectory;
import cn.melonlib.nars.names.model.entity.MelonFile;
import cn.melonlib.nars.names.model.entity.MelonNames;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.StreamUtils;

import javax.annotation.Resource;
import javax.transaction.Transactional;
import java.io.*;
import java.util.List;
import java.util.Locale;
import java.util.Objects;

import static cn.melonlib.cores.commons.comp.service.impl.WorkerBasicService.ROOT_METHOD.*;
@Service
@WorkerComment("文件管理")
@WorkerService(
        module = "names"
        ,model = @WorkerModel(
                modelType = MelonFile.class

)
        ,ignores = {LIST,LOAD_ALL,TOTAL_COUNT,SAVE,REMOVE_BY_ID,REMOVE_BY_ID_LIST}
)
public class FileService extends WorkerBasicService<MelonFile> {

    @Resource
    private NamesService namesService;

    @Resource
    private MessengerUtils messengerUtils;


    @WorkerQuery
    @WorkerComment("获取文件列表")
    public List<MelonFile> listFile(@WorkerParameter(value = "path",comment = "指定目录",required = true) String path){
        return dao.<List<MelonFile>,DefaultQuery>search(new DefaultQuery(MelonFile.class,
                JsonMap.<JsonMap<Object>>createMap().append("parent.path",JsonMap.createMap().append("eq",path)))).getResult();

    }
    @WorkerQuery
    @WorkerComment("获取读取路径")
    public String requestPath(@WorkerParameter(value = "path",comment = "逻辑路径",required = true) String path){
        MelonNames names= namesService.lookup(path);
        if(names instanceof MelonFile){
            String spath=((MelonFile) names).getStorePath();
            return spath.replace("/service/resources/MelonNames","");
        }else{
            throw new WorkerServiceException("未找到文件");
        }
    }

    @Transactional(value = Transactional.TxType.REQUIRED,rollbackOn = Exception.class)
    public MelonFile storeFile(InputStream in,String path,String fileName,Long fileSize,String contentType)throws Exception{

        Assert.isTrue(path.startsWith("/"),"保存路径必须以‘/’开头");
        String filePath=path+"/"+fileName;
        MelonNames names = namesService.lookup(filePath);
        Assert.isTrue(names==null,"资源路径已被占用");
        MelonDirectory parent=null;
        if(!Objects.equals("/",path)) {
            parent= (MelonDirectory) namesService.mkdir(path);
        }
        MelonFile melonFile=new MelonFile();
        String storePath=namesService.getStoreRootPath()+"/MelonNames/"+ DateFormatUtils.format(System.currentTimeMillis(),"yyyy/MM/dd/HH/") + IdUtil.fastSimpleUUID()+"."+FilenameUtils.getExtension(fileName);
        FileUtils.forceMkdirParent(new File(storePath));
        melonFile.setStorePath(storePath);
        melonFile.setFileSize(fileSize);
        melonFile.setExtendName(FilenameUtils.getExtension(fileName).toLowerCase(Locale.getDefault()));
        melonFile.setName(fileName);
        melonFile.setContentType(contentType);
        melonFile.setFileType(FileType.transType(contentType));
        melonFile.setPath(filePath);
        melonFile.setParent(parent);
        messengerUtils.setMessengers(melonFile);
        try(OutputStream out=new FileOutputStream(storePath)){
            StreamUtils.copy(in,out);
        }
        return dao.save(melonFile).getResult();
    }

    public InputStream readFile(String path) throws Exception{
        MelonNames file=namesService.lookup(path);
        if(file instanceof MelonFile){
            return new FileInputStream(((MelonFile) file).file());
        }else{
            throw new WorkerServiceException("查找资源不是内部存储文件");
        }
    }
}
